package com.smarttiger.zero.admin.service;

import com.smarttiger.zero.admin.dao.*;
import com.smarttiger.zero.admin.entity.*;
import com.smarttiger.zero.admin.util.Constant;
import com.smarttiger.zero.admin.util.Message;
import com.smarttiger.zero.admin.util.ZEROCacheUtil;
import com.smarttiger.zero.admin.util.ParamNames;
import com.smarttiger.zero.admin.webservice.WebServiceConfig;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.PostConstruct;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.*;

@Service
public class InterfaceService extends BaseService<InterfaceModel> {
    @Autowired
    InterfaceDao interfaceDao;

    @Autowired
    InterfaceUsersGroupDao interfaceUsersGroupDao;

    @Autowired
    WhiteListDao whiteListDao;

    @Autowired
    BlackListDao blackListDao;

    @Autowired
    InterfaceLogicDao interfaceLogicDao;

    @Autowired
    InterfaceArgsDao interfaceArgsDao;

    @Autowired
    LogicDao logicDao;

    @Autowired
    @Qualifier("endpointList")
    Map<String,EndpointImpl> endpointMap;

    @Autowired
    @Qualifier(Bus.DEFAULT_BUS_ID)
    SpringBus springBus;

    @Autowired
    ArgsDao argsDao;

    @Autowired
    WebServiceConfig webServiceConfig;

    @PostConstruct
    public void initMethod() {
        super.setDao(interfaceDao);
    }

    @ParamNames("name,page")
    public Message getInterfaces(String name, String page) {
        Message message = new Message();
        Pageable pageable = PageRequest.of(Integer.valueOf(page).intValue(), Constant.PAGESIZE, Sort.by(Sort.Direction.DESC,"createDate"));
        Page<InterfaceModel> all = interfaceDao.findAll(new Specification<InterfaceModel>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<InterfaceModel> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> predicates = new ArrayList<>();
                if (!StringUtils.isEmpty(name)) {
                    predicates.add(criteriaBuilder.like(root.get("name"), name + "%"));
                }
                criteriaQuery.orderBy(criteriaBuilder.desc(root.get("createDate")));
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        }, pageable);
        long totalElements = all.getTotalElements();
        message.setData(all.getContent());
        message.setTotal((int)totalElements);
        return message;
    }


    @ParamNames("code")
    public InterfaceModel findByCode(String code) {
        InterfaceModel it = interfaceDao.findByCode(code);
        if(it==null){return null;}
        InterfaceModel interfaceDetail = getInterfaceDetail(it.getId());
        return interfaceDetail;
    }

    @Override
    @Transactional
    public void delete(String id) {
        InterfaceModel interfaceModel = findById(id).get(0);
        String code = interfaceModel.getCode();
        webServiceConfig.stopWS(interfaceModel);
        super.delete(id);
        interfaceUsersGroupDao.deleteByInterfaceId(id);
        whiteListDao.deleteByInterfaceId(id);
        blackListDao.deleteByInterfaceId(id);
        interfaceLogicDao.deleteByInterfaceId(id);
        interfaceArgsDao.deleteByInterfaceId(id);
        ZEROCacheUtil.interfaceCache.remove("interface");


    }

    @Transactional
    public void saveConfig(Map<String, Object> data) {
        Object interfaceId = data.get("interfaceId");

        String iId = interfaceId.toString();
        interfaceUsersGroupDao.deleteByInterfaceId(iId);
        whiteListDao.deleteByInterfaceId(iId);
        blackListDao.deleteByInterfaceId(iId);

        List selectUserGroup = (List)data.get("selectUserGroup");
        for (Object userGroup : selectUserGroup) {
            InterfaceUsersGroupModel m = new InterfaceUsersGroupModel();
            m.setInterfaceId(iId);
            m.setUserGroupId(userGroup.toString());
            interfaceUsersGroupDao.save(m);
        }
        List selectUsersBlack = (List)data.get("selectUsersBlack");
        for (Object usersBlack : selectUsersBlack) {
            BlackListModel m = new BlackListModel();
            m.setInterfaceId(iId);
            m.setUsersId(usersBlack.toString());
            blackListDao.save(m);
        }
        List selectUsersWhite = (List)data.get("selectUsersWhite");
        for (Object usersWhite : selectUsersWhite) {
            WhiteListModel m = new WhiteListModel();
            m.setInterfaceId(iId);
            m.setUsersId(usersWhite.toString());
            whiteListDao.save(m);
        }
        ZEROCacheUtil.interfaceCache.remove("interface");
    }

    @ParamNames("id")
    public InterfaceModel getInterfaceDetail(String interfaceId){
        InterfaceModel one = interfaceDao.findById(interfaceId).get();
        List<InterfaceArgsModel> interfaceArgsModels = interfaceArgsDao.findAllByInterfaceId(interfaceId);
        List<LogicModel> interfaceLogics = logicDao.findLogicModelByInterfaceId(interfaceId);
        List<UsersModel> interfaceWhites = whiteListDao.queryWhiteListModelByInterfaceId(interfaceId);
        List<UsersModel> interfaceBlacks = blackListDao.queryBlackListModelByInterfaceId(interfaceId);
        List<UsersGroupModel> usersGroupModels = interfaceUsersGroupDao.queryUserGroupListModelByInterfaceId(interfaceId);
        one.setArgsModels(interfaceArgsModels);
        one.setLogicModels(interfaceLogics);
        one.setBlacklistModels(interfaceBlacks);
        one.setWhitelistModels(interfaceWhites);
        one.setUsersGroupModels(usersGroupModels);
        return one;
    }


    @Override
    public void save(InterfaceModel u) {
        super.save(u);
        ZEROCacheUtil.interfaceCache.remove("interface");
    }

    @Override
    public void update(InterfaceModel u) {
        InterfaceModel in = interfaceDao.findById(u.getId()).get();
        webServiceConfig.stopWS(in);
        u.setWsStatus("S");
        super.update(u);
        ZEROCacheUtil.interfaceCache.remove("interface");
    }

    @ParamNames("code")
    public Message publishWS(String code){
        Message message = new Message();
        InterfaceModel in = interfaceDao.findByCode(code);
        try {
            boolean b = webServiceConfig.publishWS(in);
            if(b){
                message.setCode("0");
                message.setData("logic没有配置");
                return message;
            }
        } catch (Exception e) {
            e.printStackTrace();
            message.setCode("0");
        }
        return message;
    }

    @ParamNames("code")
    public Message stopWS(String code){
        Message message = new Message();
        InterfaceModel in = interfaceDao.findByCode(code);
        webServiceConfig.stopWS(in);
        return message;
    }


}
